"""
操作系统管理服务
提供操作系统的CRUD操作和业务逻辑
"""

import logging
import uuid
from datetime import datetime
from typing import List, Optional, Dict, Any
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_, func

from src.app.database.models import OperatingSystem, Asset, BusinessSystem, Middleware, IpManagement
from src.app.database.database import get_database_manager
from src.app.modules.os.cache import OsCache
from src.app.modules.os.utils import OsUtils

logger = logging.getLogger(__name__)

class OsService:
    """操作系统管理服务类"""
    
    def __init__(self):
        self.db_manager = get_database_manager()
        self.cache = OsCache()
        self.utils = OsUtils()
    
    def create_os(self, os_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        创建操作系统
        
        Args:
            os_data: 操作系统数据
            
        Returns:
            创建结果
        """
        # 验证数据
        is_valid, error_msg = self.utils.validate_os_data(os_data)
        if not is_valid:
            return {'success': False, 'message': error_msg}
        
        # 格式化数据
        os_data = self.utils.format_os_data(os_data)
        
        # 验证设备资产是否存在
        with self.db_manager.get_session() as session:
            asset = session.query(Asset).filter(
                Asset.asset_id == os_data['asset_id']
            ).first()
            
            if not asset:
                return {'success': False, 'message': f"设备资产 {os_data['asset_id']} 不存在"}
        
        try:
            with self.db_manager.get_session() as session:
                # 生成操作系统ID
                os_id = os_data.get('os_id') or str(uuid.uuid4())
                
                # 检查是否已存在相同的操作系统
                existing_os = session.query(OperatingSystem).filter(
                    and_(
                        OperatingSystem.asset_id == os_data['asset_id'],
                        OperatingSystem.os_name == os_data['os_name'],
                        OperatingSystem.version == os_data['version']
                    )
                ).first()
                
                if existing_os:
                    return {'success': False, 'message': f"设备上已存在相同的操作系统实例"}
                
                # 检查安全设备特殊场景：安全设备通常不经过OS模块
                asset = session.query(Asset).filter(
                    Asset.asset_id == os_data['asset_id']
                ).first()
                
                if asset and asset.asset_type in ['安全设备', 'SECURITY_DEVICE']:
                    logger.warning(f"安全设备 {asset.asset_name} 通常直接关联业务系统，不建议创建操作系统实例")
                
                # 创建操作系统记录
                os_instance = OperatingSystem(
                    os_id=os_id,
                    asset_id=os_data['asset_id'],
                    os_name=os_data['os_name'],
                    version=os_data['version'],
                    install_dir=os_data.get('install_dir'),
                    install_date=os_data.get('install_date')
                )
                
                session.add(os_instance)
                session.commit()
                
                # 清除缓存
                self.cache.clear_cache()
                
                return {
                    'success': True,
                    'message': '操作系统创建成功',
                    'data': {
                        'os_id': os_id,
                        'os_name': os_data['os_name'],
                        'version': os_data['version']
                    }
                }
                
        except Exception as e:
            logger.error(f"创建操作系统失败: {str(e)}")
            return {'success': False, 'message': f"创建操作系统失败: {str(e)}"}
    
    def update_os(self, os_id: str, os_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        更新操作系统
        
        Args:
            os_id: 操作系统ID
            os_data: 更新数据
            
        Returns:
            更新结果
        """
        # 验证数据
        is_valid, error_msg = self.utils.validate_os_data(os_data, is_update=True)
        if not is_valid:
            return {'success': False, 'message': error_msg}
        
        # 格式化数据
        os_data = self.utils.format_os_data(os_data)
        
        try:
            with self.db_manager.get_session() as session:
                # 查找操作系统
                os_instance = session.query(OperatingSystem).filter(
                    OperatingSystem.os_id == os_id
                ).first()
                
                if not os_instance:
                    return {'success': False, 'message': f"操作系统 {os_id} 不存在"}
                
                # 如果更换了设备资产，验证新资产是否存在
                if 'asset_id' in os_data and os_data['asset_id'] != os_instance.asset_id:
                    asset = session.query(Asset).filter(
                        Asset.asset_id == os_data['asset_id']
                    ).first()
                    
                    if not asset:
                        return {'success': False, 'message': f"设备资产 {os_data['asset_id']} 不存在"}
                
                # 检查是否与其他操作系统重复
                if 'asset_id' in os_data or 'os_name' in os_data or 'version' in os_data:
                    new_asset_id = os_data.get('asset_id', os_instance.asset_id)
                    new_os_name = os_data.get('os_name', os_instance.os_name)
                    new_version = os_data.get('version', os_instance.version)
                    
                    existing_os = session.query(OperatingSystem).filter(
                        and_(
                            OperatingSystem.asset_id == new_asset_id,
                            OperatingSystem.os_name == new_os_name,
                            OperatingSystem.version == new_version,
                            OperatingSystem.os_id != os_id
                        )
                    ).first()
                    
                    if existing_os:
                        return {'success': False, 'message': f"设备上已存在相同的操作系统实例"}
                
                # 更新字段
                for field in ['asset_id', 'os_name', 'version', 'install_dir', 'install_date']:
                    if field in os_data:
                        setattr(os_instance, field, os_data[field])
                
                os_instance.update_time = datetime.now()
                session.commit()
                
                # 清除缓存
                self.cache.clear_cache()
                
                return {
                    'success': True,
                    'message': '操作系统更新成功',
                    'data': {
                        'os_id': os_id,
                        'os_name': os_instance.os_name,
                        'version': os_instance.version
                    }
                }
                
        except Exception as e:
            logger.error(f"更新操作系统失败: {str(e)}")
            return {'success': False, 'message': f"更新操作系统失败: {str(e)}"}
    
    def delete_os(self, os_id: str) -> Dict[str, Any]:
        """
        删除操作系统
        
        Args:
            os_id: 操作系统ID
            
        Returns:
            删除结果
        """
        try:
            with self.db_manager.get_session() as session:
                # 查找操作系统
                os_instance = session.query(OperatingSystem).filter(
                    OperatingSystem.os_id == os_id
                ).first()
                
                if not os_instance:
                    return {'success': False, 'message': f"操作系统 {os_id} 不存在"}
                
                # 检查是否有关联的业务系统
                business_systems_count = session.query(func.count(BusinessSystem.system_id)).filter(
                    BusinessSystem.os_id == os_id
                ).scalar()
                
                if business_systems_count > 0:
                    return {
                        'success': False, 
                        'message': f"该操作系统下还有 {business_systems_count} 个业务系统，无法删除"
                    }
                
                # 检查是否有关联的中间件
                middlewares_count = session.query(func.count(Middleware.mw_id)).filter(
                    Middleware.os_id == os_id
                ).scalar()
                
                if middlewares_count > 0:
                    return {
                        'success': False, 
                        'message': f"该操作系统下还有 {middlewares_count} 个中间件，无法删除"
                    }
                
                # 检查是否有关联的IP地址
                ip_count = session.query(func.count(IpManagement.ip)).filter(
                    IpManagement.os_id == os_id
                ).scalar()
                
                if ip_count > 0:
                    return {
                        'success': False, 
                        'message': f"该操作系统还绑定了 {ip_count} 个IP地址，无法删除"
                    }
                
                # 删除操作系统
                session.delete(os_instance)
                session.commit()
                
                # 清除缓存
                self.cache.clear_cache()
                
                return {
                    'success': True,
                    'message': '操作系统删除成功',
                    'data': {'os_id': os_id}
                }
                
        except Exception as e:
            logger.error(f"删除操作系统失败: {str(e)}")
            return {'success': False, 'message': f"删除操作系统失败: {str(e)}"}
    
    def get_os_by_id(self, os_id: str) -> Optional[Dict[str, Any]]:
        """
        根据ID获取操作系统
        
        Args:
            os_id: 操作系统ID
            
        Returns:
            操作系统信息或None
        """
        # 先从缓存获取
        cached_data = self.cache.get_os(os_id)
        if cached_data:
            return cached_data
        
        try:
            with self.db_manager.get_session() as session:
                os_instance = session.query(OperatingSystem).filter(
                    OperatingSystem.os_id == os_id
                ).first()
                
                if not os_instance:
                    return None
                
                # 获取关联的设备资产信息
                asset = session.query(Asset).filter(
                    Asset.asset_id == os_instance.asset_id
                ).first()
                
                # 统计关联信息
                business_systems_count = session.query(func.count(BusinessSystem.system_id)).filter(
                    BusinessSystem.os_id == os_id
                ).scalar()
                
                middlewares_count = session.query(func.count(Middleware.mw_id)).filter(
                    Middleware.os_id == os_id
                ).scalar()
                
                ip_count = session.query(func.count(IpManagement.ip)).filter(
                    IpManagement.os_id == os_id
                ).scalar()
                
                os_data = {
                    'os_id': os_instance.os_id,
                    'asset_id': os_instance.asset_id,
                    'asset_name': asset.asset_name if asset else '未知设备',
                    'asset_type': asset.asset_type if asset else '未知类型',
                    'os_name': os_instance.os_name,
                    'version': os_instance.version,
                    'install_dir': os_instance.install_dir,
                    'install_date': os_instance.install_date.strftime('%Y-%m-%d') if os_instance.install_date else None,
                    'create_time': os_instance.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'update_time': os_instance.update_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'business_systems_count': business_systems_count,
                    'middlewares_count': middlewares_count,
                    'ip_count': ip_count
                }
                
                # 缓存数据
                self.cache.set_os(os_id, os_data)
                
                return os_data
                
        except Exception as e:
            logger.error(f"获取操作系统失败: {str(e)}")
            return None
    
    def get_os_list(self, filters: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]:
        """
        获取操作系统列表
        
        Args:
            filters: 筛选条件
            
        Returns:
            操作系统列表
        """
        try:
            with self.db_manager.get_session() as session:
                query = session.query(OperatingSystem, Asset).join(
                    Asset, OperatingSystem.asset_id == Asset.asset_id
                )
                
                # 应用筛选条件
                if filters:
                    if 'asset_id' in filters:
                        query = query.filter(OperatingSystem.asset_id == filters['asset_id'])
                    
                    if 'os_name' in filters and filters['os_name']:
                        query = query.filter(OperatingSystem.os_name.like(f"%{filters['os_name']}%"))
                    
                    if 'version' in filters and filters['version']:
                        query = query.filter(OperatingSystem.version.like(f"%{filters['version']}%"))
                    
                    if 'asset_type' in filters and filters['asset_type']:
                        query = query.filter(Asset.asset_type == filters['asset_type'])
                
                # 执行查询
                results = query.all()
                
                os_list = []
                for os_instance, asset in results:
                    # 统计关联信息
                    business_systems_count = session.query(func.count(BusinessSystem.system_id)).filter(
                        BusinessSystem.os_id == os_instance.os_id
                    ).scalar()
                    
                    middlewares_count = session.query(func.count(Middleware.mw_id)).filter(
                        Middleware.os_id == os_instance.os_id
                    ).scalar()
                    
                    ip_count = session.query(func.count(IpManagement.ip)).filter(
                        IpManagement.os_id == os_instance.os_id
                    ).scalar()
                    
                    os_data = {
                        'os_id': os_instance.os_id,
                        'asset_id': os_instance.asset_id,
                        'asset_name': asset.asset_name,
                        'asset_type': asset.asset_type,
                        'os_name': os_instance.os_name,
                        'version': os_instance.version,
                        'install_dir': os_instance.install_dir,
                        'install_date': os_instance.install_date.strftime('%Y-%m-%d') if os_instance.install_date else None,
                        'create_time': os_instance.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'update_time': os_instance.update_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'business_systems_count': business_systems_count,
                        'middlewares_count': middlewares_count,
                        'ip_count': ip_count
                    }
                    
                    os_list.append(os_data)
                
                return os_list
                
        except Exception as e:
            logger.error(f"获取操作系统列表失败: {str(e)}")
            return []
    
    def get_os_statistics(self) -> Dict[str, Any]:
        """
        获取操作系统统计信息
        
        Returns:
            统计信息字典
        """
        try:
            with self.db_manager.get_session() as session:
                # 总数统计
                total_count = session.query(func.count(OperatingSystem.os_id)).scalar()
                
                # 按操作系统名称分布
                os_distribution = session.query(
                    OperatingSystem.os_name,
                    func.count(OperatingSystem.os_id)
                ).group_by(OperatingSystem.os_name).all()
                
                # 按设备类型分布
                asset_type_distribution = session.query(
                    Asset.asset_type,
                    func.count(OperatingSystem.os_id)
                ).join(Asset, OperatingSystem.asset_id == Asset.asset_id).group_by(
                    Asset.asset_type
                ).all()
                
                # 最近安装的操作系统
                recent_os = session.query(OperatingSystem, Asset).join(
                    Asset, OperatingSystem.asset_id == Asset.asset_id
                ).order_by(OperatingSystem.create_time.desc()).limit(5).all()
                
                recent_os_list = []
                for os_instance, asset in recent_os:
                    recent_os_list.append({
                        'os_id': os_instance.os_id,
                        'os_name': os_instance.os_name,
                        'version': os_instance.version,
                        'asset_name': asset.asset_name,
                        'create_time': os_instance.create_time.strftime('%Y-%m-%d %H:%M:%S')
                    })
                
                return {
                    'total_count': total_count,
                    'os_distribution': [
                        {'name': name, 'count': count} for name, count in os_distribution
                    ],
                    'asset_type_distribution': [
                        {'name': name, 'count': count} for name, count in asset_type_distribution
                    ],
                    'recent_os': recent_os_list
                }
                
        except Exception as e:
            logger.error(f"获取操作系统统计信息失败: {str(e)}")
            return {
                'total_count': 0,
                'os_distribution': [],
                'asset_type_distribution': [],
                'recent_os': []
            }
    
    def get_os_details(self, os_id: str) -> Dict[str, Any]:
        """
        获取操作系统详细信息
        
        Args:
            os_id: 操作系统ID
            
        Returns:
            详细信息字典
        """
        os_data = self.get_os_by_id(os_id)
        if not os_data:
            return {}
        
        try:
            with self.db_manager.get_session() as session:
                # 获取关联的业务系统
                business_systems = session.query(BusinessSystem).filter(
                    BusinessSystem.os_id == os_id
                ).all()
                
                os_data['business_systems'] = [
                    {
                        'system_id': bs.system_id,
                        'system_type': bs.system_type,
                        'system_name': bs.system_name,
                        'description': bs.description,
                        '负责人': bs.负责人,
                        'department': bs.department
                    }
                    for bs in business_systems
                ]
                
                # 获取关联的中间件
                middlewares = session.query(Middleware).filter(
                    Middleware.os_id == os_id
                ).all()
                
                os_data['middlewares'] = [
                    {
                        'mw_id': mw.mw_id,
                        'mw_type': mw.mw_type,
                        'name': mw.name,
                        'version': mw.version,
                        'install_dir': mw.install_dir,
                        'port': mw.port
                    }
                    for mw in middlewares
                ]
                
                # 获取关联的IP地址
                ips = session.query(IpManagement).filter(
                    IpManagement.os_id == os_id
                ).all()
                
                os_data['ips'] = [
                    {
                        'ip': ip.ip,
                        'subnet_mask': ip.subnet_mask,
                        'vlan': ip.vlan,
                        'purpose': ip.purpose,
                        'status': ip.status,
                        'allocation_duration': ip.allocation_duration
                    }
                    for ip in ips
                ]
                
                return os_data
                
        except Exception as e:
            logger.error(f"获取操作系统详细信息失败: {str(e)}")
            return os_data